package conMgr.ui.papers;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JLabel;
import javax.swing.JPanel;

import conMgr.model.Paper;
import conMgr.model.Review;
import conMgr.model.User;
import conMgr.model.UserType;
import conMgr.ui.util.SelectUserView;
import conMgr.ui.util.Ui;

/**
 * Provides a view for subprogram chairs to assign new reviewers to a paper.   
 * @author is4@uw.edu
 */
public class AssignReviewersView extends JPanel
{
	/**
	 * The serialization ID for this class.
	 */
	private static final long serialVersionUID = 1124527169434433043L;
	
	/**
	 * The paper to which reviewers will be assigned.
	 */
	private final Paper paper;
	
	/**
	 * A list of the new reviewers to assign.
	 */
	private final List<User> newReviewers;
	
	/**
	 * Initializes a new AssignReviewersView.
	 * @param paper The paper to which reviewers will be assigned.
	 */
	public AssignReviewersView(final Paper paper)
	{
		this.paper = paper;
		newReviewers = new ArrayList<User>();
		
		setLayout(new GridBagLayout());
		
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.CENTER;
		add(Ui.createButton("Select Reviewers", new PickUsersAction()), constraints);
	}
	
	/**
	 * Displays a new reviewer in this panel with an "X" button for removal.
	 * @param reviewer The reviewer to display.
	 * @param row The row to display the user in.
	 */
	private void displayNewReviewer(final User reviewer, final int row)
	{
		final JLabel label = new JLabel(reviewer.getName());
		
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.gridx = 0;
		constraints.gridy = row;
		constraints.anchor = GridBagConstraints.WEST;
		add(label, constraints);
		
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.gridx = 1;
		constraints.gridy = row;
		constraints.anchor = GridBagConstraints.WEST;
		add(Ui.createButton("X", new RemoveReviewerAction(reviewer)), constraints);
	}
	
	/**
	 * Displays a list of the users selected as new reviewers.
	 */
	private void refreshNewReviewers()
	{
		for (int i = getComponentCount() - 1; i > 0; i--)
			remove(i);
		
		int row = 1;
		
		for (User user : newReviewers)
			displayNewReviewer(user, row++);
		
		revalidate();
		repaint();
	}
	
	/**
	 * Assigns reviewers to the paper.
	 */
	public void save()
	{
		final List<User> currentReviewers = new ArrayList<User>();
		
		for (Review review : paper.getPaperReviews())
			currentReviewers.add(review.getReviewer());
		
		for (User reviewer : newReviewers)
			if (!currentReviewers.contains(reviewer))
				new Review(reviewer, paper);
	}
	
	/**
	 * Provides an action for the pick reviewers button. 
	 */
	class PickUsersAction extends AbstractAction
	{
		/**
		 * The serialization ID of this class.
		 */
		private static final long serialVersionUID = 3067664721769502500L;

		/**
		 * Handles the action. Shows the SelectUserView.
		 */
		@Override
		public void actionPerformed(final ActionEvent arg0)
		{
			final List<User> users = SelectUserView.getUsers(UserType.REVIEWER);
			
			if (users == null)
				return;
			
			for (User user : users)
				if (!AssignReviewersView.this.newReviewers.contains(user))
					AssignReviewersView.this.newReviewers.add(user);
			
			AssignReviewersView.this.refreshNewReviewers();
		}
	}
	
	/**
	 * Provides an action that removes a reviewer from the list of new
	 * reviewers.
	 * @author is4@uw.edu
	 */
	class RemoveReviewerAction extends AbstractAction
	{
		/**
		 * The serialization ID of this class.
		 */
		private static final long serialVersionUID = 466215479314910260L;

		/**
		 * The reviewer to remove.
		 */
		private final User reviewer;
		
		/**
		 * Initializes a new Remove Reviewer action.
		 * @param reviewer The reviewer to remove.
		 */
		private RemoveReviewerAction(final User reviewer)
		{
			this.reviewer = reviewer;
		}
		
		/**
		 * Handles the action. Removes the reviewer from the list of new
		 * reviewers.
		 */
		@Override
		public void actionPerformed(final ActionEvent arg0)
		{
			AssignReviewersView.this.newReviewers.remove(reviewer);
			AssignReviewersView.this.refreshNewReviewers();
		}
	}
}
